#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <assert.h>
#include <signal.h>
#include <stdio.h>
#include "preforkserver.h"

PidsBoadManager * PreForkServer :: m_ptPidsBoadManager;

static void OnChildProcEnd(int signo)
{
	//............signo	
	int status;
	pid_t pid;
	while ( (pid=waitpid(-1, &status, WNOHANG)) > 0 )
	{
		PreForkServer::m_ptPidsBoadManager->SetState(pid,eEmpty);	
	}
}	

PreForkServer::PreForkServer(int key, unsigned int aiSubprocnum)
{
	m_iSubprocnum = aiSubprocnum;	
	m_ptPidsBoadManager = new PidsBoadManager(key, aiSubprocnum);
}

PreForkServer::~PreForkServer()
{
	if ( m_ptPidsBoadManager != NULL )
		delete m_ptPidsBoadManager;
}

void PreForkServer::BeforeRun()
{
}

int PreForkServer::Init()
{
	return m_ptPidsBoadManager->Init();
}

int PreForkServer::Run()
{
	int ret = -1;
    pid_t pid = -1;	
	
	ret = Init();
	
	if ( ret != 0 )
	{ 
		return -2;//init fail
	}

	assert( signal(SIGCHLD,OnChildProcEnd) != SIG_ERR );
	BeforeRun();
	while ( m_iSubprocnum > 0 )
	{
		pid = fork();
		if (pid < 0) // fork error
		{
			continue;
		}
		else if (pid == 0) // child 
		{
			ChildRun();
		}
		else // father 
		{
			m_ptPidsBoadManager->New(pid);
			--m_iSubprocnum;	
		}
	}

	//
	
	while (true)
	{
		for (int i=0; i<m_iSubprocnum; ++i)
		{
			if ( m_ptPidsBoadManager->CheckState(eEmpty, pid) )
			{
				pid = fork();
				if (pid < 0)
				{
					printf("fork error\n");
				}
				else if (pid == 0)
				{
					ChildRun();
				}
				else
				{
					m_ptPidsBoadManager->New(pid);
				}
			}
		}
		usleep(100*1000);
	}
}

